package com.xiaozhi.dialogue.llm.memory;

import cn.hutool.core.util.IdUtil;
import com.github.pagehelper.util.StringUtil;
import com.xiaozhi.common.web.PageFilter;
import com.xiaozhi.entity.*;
import com.xiaozhi.service.*;

import org.jetbrains.annotations.NotNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.Instant;
import java.time.temporal.ChronoUnit;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 基于数据库的聊天记忆实现
 * 全局单例类，负责Conversatin里消息的获取、保存、清理。
 * 后续考虑：DatabaseChatMemory 是对 SysMessageService 的一层薄封装，未来或者有可能考虑合并这两者。
 */
@Service
public class DatabaseChatMemory implements ChatMemory {
    private static final Logger logger = LoggerFactory.getLogger(DatabaseChatMemory.class);

    private final SysMessageService messageService;


    @Autowired
    private ITKeywordsService keywordsService;


    @Autowired
    private OpenAiService openAiService;


    @Autowired
    private SysRoleService roleService;

    @Autowired
    private ITCpService cpService;
    @Autowired
    private ITCpRecordService cpRecordService;
    private String[] keywordsjx;

    @Autowired
    public DatabaseChatMemory(SysMessageService messageService) {
        this.messageService = messageService;
    }

    @Override
    public void addMessage(String deviceId, String deviceName, String sessionId, String sender, String content, Integer roleId, String messageType, Long timeMillis, String documentTypeId, String documentTypeName) {
        // 异步虚拟线程处理持久化。
        Thread.startVirtualThread(() -> {
            try {
                SysMessage message = new SysMessage();
                message.setDeviceName(deviceName);
                message.setDeviceId(deviceId);
                message.setSessionId(sessionId);
                message.setSender(sender);
                message.setMessage(content);
                message.setRoleId(roleId);
                message.setMessageType(messageType);
                Instant instant = Instant.ofEpochMilli(timeMillis).truncatedTo(ChronoUnit.SECONDS);
                message.setCreateTime(Date.from(instant));
                message.setDocumentTypeId(documentTypeId);
                message.setDocumentTypeName(documentTypeName);
                messageService.add(message);
            } catch (Exception e) {
                logger.error("保存消息时出错: {}", e.getMessage(), e);
            }
        });

    }

    @Override
    public void addMessage(String deviceId, String deviceName, String sessionId, String sender, String content, Integer roleId, String messageType, Long timeMillis, String documentTypeId, String documentTypeName, String dzStatus,Integer  H5UserId) {

        keywordsjx = null;
        // 异步虚拟线程处理持久化。
        Thread.startVirtualThread(() -> {
            try {
                SysMessage message = new SysMessage();
                message.setDeviceName(deviceName);
                message.setDeviceId(deviceId);
                message.setSessionId(sessionId);
                message.setSender(sender);
                message.setMessage(content);
                message.setRoleId(roleId);
                message.setMessageType(messageType);
                Instant instant = Instant.ofEpochMilli(timeMillis).truncatedTo(ChronoUnit.SECONDS);
                message.setCreateTime(Date.from(instant));
                message.setDocumentTypeId(documentTypeId);
                message.setDocumentTypeName(documentTypeName);
                message.setDzStatus(dzStatus);
                message.setIsPush("0");
                message.setH5userId(H5UserId);
                if ("user".equals(sender)) {
                    String gjcChatCpReply = openAiService.getGjcChatCpReply(content);
                    if (StringUtil.isNotEmpty(gjcChatCpReply) && !"没有关键词".equals(gjcChatCpReply)) {
                        keywordsjx = gjcChatCpReply.split("\\$");
                        // 改成逗号分割的字符串
                        if (keywordsjx.length > 0) {
                            List<String> keywords = new ArrayList<>(Arrays.asList(keywordsjx));
                            String collect = keywords.stream().collect(Collectors.joining(","));
                            message.setBcRemark(collect);
                        }
                    }
                } else {
                    message.setBcRemark("");
                }
                messageService.add(message);
                // 保存关键词
                if("user".equals(sender)   && keywordsjx!=null ){
                    for (int i = 0; i <keywordsjx.length ; i++) {
                        String keyword = keywordsjx[i];
                        TKeywords keywords = new TKeywords();
                        keywords.setId(IdUtil.randomUUID());
                        keywords.setDeviceId(deviceId);
                        keywords.setSessionId(sessionId);
                        keywords.setMessage(content);
                        keywords.setRoleId(roleId);
                        keywords.setMessageType(messageType);
                        keywords.setCreateTime(Date.from(instant));
                        keywords.setDocumentTypeId(documentTypeId);
                        keywords.setDocumentTypeName(documentTypeName);
                        keywords.setKeyWord(keyword);
                        keywordsService.insertTKeywords(keywords);
                    }
                }
                if ("user".equals(sender)) {
                    // 提取产品信息
                    String chatCpReplyQu = openAiService.getChatCpReplyQu(content);
                    if(!"未获取到产品名称".equals(chatCpReplyQu)){
                        String[] splitproducts = chatCpReplyQu.split("\\$");
                        for (int i = 0; i <splitproducts.length ; i++) {
                            if (StringUtil.isNotEmpty(roleId + "")) {
                                String splitproduct = splitproducts[i];
                                SysRole role = roleService.selectRoleById(roleId);
                                //用户Id
                                Integer userId = role.getUserId();
                                // 查询用户的产品
                                TCp cp = new TCp();
                                cp.setUserId(userId + "");
                                List<TCp> tCps = cpService.selectTCpList(cp);
                                //  tCps  stream 产品名称
                                List<String> productNames = tCps.stream().map(TCp::getName).toList();
                                // 检查关键词是否匹配任何产品名称
                                if (productNames.contains(splitproduct)) {
                                    TCpRecord tCpRecord = new TCpRecord();
                                    tCpRecord.setId(IdUtil.randomUUID());
                                    tCpRecord.setName(splitproduct);
                                    tCpRecord.setUserId(userId + "");
                                    tCpRecord.setCreateTime(Date.from(instant));
                                    cpRecordService.insertTCpRecord(tCpRecord);
                                }
                            }
                        }
                    }
                }




            } catch (Exception e) {
                logger.error("保存消息时出错: {}", e.getMessage(), e);
            }
        });



    }



    @Override
    public List<SysMessage> getMessages(String deviceId, String messageType, Integer limit) {
        try {
            SysMessage queryMessage = new SysMessage();
            queryMessage.setDeviceId(deviceId);
            queryMessage.setMessageType(messageType);
            PageFilter pageFilter = new PageFilter(1, limit);
            List<SysMessage> messages = messageService.query(queryMessage, pageFilter);
            messages = new ArrayList<>(messages);
            messages.sort(Comparator.comparing(Base::getCreateTime));
            return messages;
            // return messages;
        } catch (Exception e) {
            logger.error("获取历史消息时出错: {}", e.getMessage(), e);
            return new ArrayList<>();
        }
    }

    @Override
    public List<SysMessage> getMessagesH5(Integer roleId ,Integer  h5UserId, String sessionId,String messageType, Integer limit) {
        try {
            SysMessage queryMessage = new SysMessage();
            queryMessage.setRoleId(roleId);
            if(h5UserId!=null){
                queryMessage.setH5userId(h5UserId);
            }else{
                queryMessage.setSessionId(sessionId);
            }
            queryMessage.setMessageType(messageType);
            PageFilter pageFilter = new PageFilter(1, limit);
            List<SysMessage> messages = messageService.query(queryMessage, pageFilter);
            messages = new ArrayList<>(messages);
            messages.sort(Comparator.comparing(Base::getCreateTime));
            return messages;
            // return messages;
        } catch (Exception e) {
            logger.error("获取历史消息时出错: {}", e.getMessage(), e);
            return new ArrayList<>();
        }
    }


    @Override
    public void clearMessages(String deviceId) {
        try {
            // 清除设备的历史消息
            SysMessage deleteMessage = new SysMessage();
            deleteMessage.setDeviceId(deviceId);
            // messageService.update(deleteMessage);
        } catch (Exception e) {
            logger.error("清除设备历史记录时出错: {}", e.getMessage(), e);
        }
    }

}
